package com.jtw.common.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.lionsoul.ip2region.Util;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.lang.reflect.Method;
import java.util.Calendar;

/**
 * ip解析工具
 */
@Slf4j
public abstract class IpUtil {

	private static String dbPath = IpUtil.class.getResource("/ip2region.db").getPath();
	private static File file = new File(dbPath);
	private static int algorithm = DbSearcher.BTREE_ALGORITHM; //B-tree

	static{
		if (file.exists() == false) {
			String tmpDir = System.getProperties().getProperty("java.io.tmpdir");
			dbPath = tmpDir + "ip.db";
			file = new File(dbPath);
			try {
				FileUtils.copyInputStreamToFile(
						IpUtil.class.getClassLoader().getResourceAsStream("classpath:ip2region.db"), file
				);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	/**
	 * 获取客户端IP地址
	 * @param request
	 * @return
	 */
	public static String getIpAddress(HttpServletRequest request){
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	/**
	 * 根据ip解析物理地址
	 * @param ip
	 * @return
	 */
	public static String getIpFromAttribution(String ip){
		//DbSearcher.BINARY_ALGORITHM //Binary
		//DbSearcher.MEMORY_ALGORITYM //Memory
		DbConfig config=null;
		DbSearcher searcher=null;
		try {
			config = new DbConfig();
			searcher = new DbSearcher(config, dbPath);
			//define the method
			Method method = null;
			switch ( algorithm )
			{
				case DbSearcher.BTREE_ALGORITHM:
					method = searcher.getClass().getMethod("btreeSearch", String.class);
					break;
				case DbSearcher.BINARY_ALGORITHM:
					method = searcher.getClass().getMethod("binarySearch", String.class);
					break;
				case DbSearcher.MEMORY_ALGORITYM:
					method = searcher.getClass().getMethod("memorySearch", String.class);
					break;
			}
			DataBlock dataBlock = null;
			if (Util.isIpAddress(ip) == false ) {
				log.error("Error: Invalid ip address");
			}
			dataBlock  = (DataBlock) method.invoke(searcher, ip);
			return dataBlock.getRegion();
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				searcher.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return ip+"解析失败";
	}

	public static void main(String[] args) {
		System.out.println(getIpFromAttribution("36.225.114.78"));
	}
}
